package com.my.test.spring.aop;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ParameterMode;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;



public class LogDetailHelper {

	/**
     * 获取将要执行的sql语句
     * @param boundSql
     * @param parameterObject
     * @param sqlString
     * @return
     */
    public static String getSql(Configuration configuration,BoundSql boundSql,Object parameterObject,String sqlString){
    	if (boundSql==null||sqlString.isEmpty()) {
			return "";
		}
    	String targetSql=fillSql(configuration,boundSql,parameterObject,sqlString);
//    	//只有select时才需要添加分页语句
//        if (!(targetSql.indexOf("update")>=0||
//        	targetSql.indexOf("insert")>=0||
//        	targetSql.indexOf("delete")>=0)) {
////        	Page page=SqlUtil.getLocalPage();
//        	if (page!=null) {//此时是分页
//        		targetSql=String.format("select count(*) from (%s) tmp_count;\n%s limit %s offset %s ", 
//        				targetSql,targetSql,page.getPageSize(),page.getStartRow());
//    		}
//		}
//        String dbType=DBContextHolder.getDbType();
//        targetSql=(dbType==null?"默认":dbType)+"级别:"+targetSql;
        //logger.debug(targetSql);
	    return targetSql;
    }
    /**
     * 将sql的参数填充到sql语句中
     * @param configuration
     * @param boundSql
     * @param parameterObject
     * @param sqlString
     * @return
      * @author zhaohailong
      * @date 20160627
     */
    private static String fillSql(Configuration configuration,BoundSql boundSql,Object parameterObject,String sqlString){
    	if (sqlString.indexOf("?")<0) {
			return sqlString;
		}
    	List<String> values=getValuesList(configuration,boundSql,parameterObject);
    	if (values==null||values.size()==0) {
			throw new RuntimeException("解析sql语句时异常，没取到参数");
		}
	    Pattern p = Pattern.compile("\\?");
	    Matcher m = p.matcher(sqlString);
	    StringBuffer sb = new StringBuffer();
	    int index=0;
	    while(m.find()) {
	    	if (index>=values.size()) {
				throw new RuntimeException("sql语句中参数个数和给定的参数个数不匹配");
			}
	        m.appendReplacement(sb, values.get(index));
	        index++;
	    }
	    m.appendTail(sb);
	    return sb.toString();
    }

    /**
     * 获取sql语句中需要的参数的值
     * @param configuration
     * @param boundSql
     * @param parameterObject
     * @return
     * @author zhaohailong
     * @date 20160627
     */
    private static List<String> getValuesList(Configuration configuration,BoundSql boundSql,Object parameterObject){
    	List<String> valuesList = new ArrayList<String>();
    	if (parameterObject==null) {
			return valuesList;
		}
    	List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
		if (parameterMappings != null&&parameterMappings.size()>0) {
			String targetValue="";
			Object value=null;
			String propertyName="";
			TypeHandlerRegistry typeHandlerRegistry=configuration.getTypeHandlerRegistry();
			for (int i = 0; i < parameterMappings.size(); i++) {
				ParameterMapping parameterMapping = parameterMappings.get(i);
				if (parameterMapping.getMode() != ParameterMode.OUT) {
					propertyName= parameterMapping.getProperty();
					if (boundSql.hasAdditionalParameter(propertyName)) { 
						value = boundSql.getAdditionalParameter(propertyName);
					} else if (parameterObject == null) {
						value = null;
					}else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
			            value = parameterObject;
			        } else {
						MetaObject metaObject = configuration.newMetaObject(parameterObject);
						value = metaObject.getValue(propertyName);
					}
					if (value==null) {
						targetValue = "NULL";
					}else if (value instanceof Date) {
//			    		targetValue = String.format("'%s'", ParseHelper.ToDateString((Date) value));
			    	}else if (value instanceof String) {
			    		targetValue = String.format("'%s'", value);
					}else {
						targetValue = value.toString();
					}
					valuesList.add(targetValue);
				}
			}
		}
		return valuesList;
    }
}
